use chrono::Utc;
use sha3::{Digest, Sha3_256};
use sha3::digest::Update;
use crate::utils;

// #[derive(Debug, Serialize, Deserialize)]
pub struct BlockHeader {
    pub time: i64,  // 时间戳
    // pub tx_hash: Vec<u8>,
    pub pre_hash: Vec<u8>, // 上一个block的hash
}

// #[derive(Debug, Serialize, Deserialize)]
#[derive(Debug)]
pub struct Block {
    // 版本号
    pub version: u64,

    // 前block 的 hash
    pub prev_hash: Vec<u8>,

    // 交易的根hash
    pub merkle_root: Vec<u8>,

    // 时间戳
    pub time_stamp: i64,

    // 难度值， 系统提供一个难度值， 用于计算一个hash
    pub bits: u64,

    // 随机数  挖矿要求的数值
    pub nonce: u32,

    // 当前block的hash
    pub hash: Vec<u8>,

    // 数据
    pub data: Vec<u8>,
    // pub transaction: Vec<Transaction>,
}

impl Block {
    // pub fn serilaze(&self) -> Vec<u8>
    // {
    //     let seirialize = bincode::serialize(&self).unwrap();
    //     seirialize
    // }
    //
    // pub fn derilaze(bytes: &[u8]) -> Self
    // {
    //     let obj = bincode::deserialize(bytes).unwrap();
    //     obj
    // }

    pub fn new_block(data: Vec<u8>, prev_hash: Vec<u8>) -> Block {
        let mut block = Block {
            version: 0,

            prev_hash: prev_hash,
            merkle_root: Vec::new(),
            time_stamp: Utc::now().timestamp(),

            bits: 0,
            nonce: 0,
            hash: Vec::new(),
            data,
        };
        block.set_hash();
        block
    }


    pub fn set_hash(&mut self) {

        //to_le_bytes 以小端字节顺序将这个整数的内存表示形式返回为字节数组
        let data = vec![
            self.version.to_le_bytes().as_slice(),
            self.prev_hash.as_slice(),
            self.merkle_root.as_slice(),
            self.time_stamp.to_le_bytes().as_slice(),
            self.bits.to_le_bytes().as_slice(),
            self.nonce.to_le_bytes().as_slice(),
            self.data.as_slice(),
        ].concat();

        let hash = utils::get_hash(&data);
        self.hash = hash;
    }
}


#[test]
fn test_to_le_bytes() {
    let i: i32 = 234;

    let binding = i.to_le_bytes();
    let nn = binding.as_slice();

    println!("nn is {:?}", nn.to_vec());
}